{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 03自定义层"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-08-18T07:07:16.604374Z",
     "iopub.status.busy": "2023-08-18T07:07:16.603752Z",
     "iopub.status.idle": "2023-08-18T07:07:17.492480Z",
     "shell.execute_reply": "2023-08-18T07:07:17.491482Z"
    },
    "origin_pos": 2,
    "tab": [
     "pytorch"
    ]
   },
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn.functional as F\n",
    "from torch import nn\n",
    "\n",
    "\n",
    "class CenteredLayer(nn.Module):\n",
    "    def __init__(self):\n",
    "        super().__init__()\n",
    "\n",
    "    def forward(self, X):\n",
    "        return X - X.mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-08-18T07:07:17.497408Z",
     "iopub.status.busy": "2023-08-18T07:07:17.497077Z",
     "iopub.status.idle": "2023-08-18T07:07:17.508357Z",
     "shell.execute_reply": "2023-08-18T07:07:17.507175Z"
    },
    "origin_pos": 7,
    "tab": [
     "pytorch"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([-2., -1.,  0.,  1.,  2.])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "layer = CenteredLayer()\n",
    "layer(torch.FloatTensor([1, 2, 3, 4, 5]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-08-18T07:07:17.513247Z",
     "iopub.status.busy": "2023-08-18T07:07:17.512547Z",
     "iopub.status.idle": "2023-08-18T07:07:17.518968Z",
     "shell.execute_reply": "2023-08-18T07:07:17.517886Z"
    },
    "origin_pos": 12,
    "tab": [
     "pytorch"
    ]
   },
   "outputs": [],
   "source": [
    "net = nn.Sequential(nn.Linear(8, 128), CenteredLayer())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-08-18T07:07:17.523517Z",
     "iopub.status.busy": "2023-08-18T07:07:17.523140Z",
     "iopub.status.idle": "2023-08-18T07:07:17.534718Z",
     "shell.execute_reply": "2023-08-18T07:07:17.533593Z"
    },
    "origin_pos": 16,
    "tab": [
     "pytorch"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor(7.4506e-09, grad_fn=<MeanBackward0>)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Y = net(torch.rand(4, 8))\n",
    "Y.mean()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-08-18T07:07:17.539101Z",
     "iopub.status.busy": "2023-08-18T07:07:17.538729Z",
     "iopub.status.idle": "2023-08-18T07:07:17.546162Z",
     "shell.execute_reply": "2023-08-18T07:07:17.545105Z"
    },
    "origin_pos": 21,
    "tab": [
     "pytorch"
    ]
   },
   "outputs": [],
   "source": [
    "class MyLinear(nn.Module):\n",
    "    def __init__(self, in_units, units):\n",
    "        super().__init__()\n",
    "        self.weight = nn.Parameter(torch.randn(in_units, units))\n",
    "        self.bias = nn.Parameter(torch.randn(units,))\n",
    "    def forward(self, X):\n",
    "        linear = torch.matmul(X, self.weight.data) + self.bias.data\n",
    "        return F.relu(linear)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-08-18T07:07:17.550522Z",
     "iopub.status.busy": "2023-08-18T07:07:17.550152Z",
     "iopub.status.idle": "2023-08-18T07:07:17.558364Z",
     "shell.execute_reply": "2023-08-18T07:07:17.557338Z"
    },
    "origin_pos": 28,
    "tab": [
     "pytorch"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Parameter containing:\n",
       "tensor([[ 0.1775, -1.4539,  0.3972],\n",
       "        [-0.1339,  0.5273,  1.3041],\n",
       "        [-0.3327, -0.2337, -0.6334],\n",
       "        [ 1.2076, -0.3937,  0.6851],\n",
       "        [-0.4716,  0.0894, -0.9195]], requires_grad=True)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linear = MyLinear(5, 3)\n",
    "linear.weight"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-08-18T07:07:17.562706Z",
     "iopub.status.busy": "2023-08-18T07:07:17.562337Z",
     "iopub.status.idle": "2023-08-18T07:07:17.570015Z",
     "shell.execute_reply": "2023-08-18T07:07:17.568916Z"
    },
    "origin_pos": 32,
    "tab": [
     "pytorch"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0., 0., 0.],\n",
       "        [0., 0., 0.]])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linear(torch.rand(2, 5))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "execution": {
     "iopub.execute_input": "2023-08-18T07:07:17.574378Z",
     "iopub.status.busy": "2023-08-18T07:07:17.574000Z",
     "iopub.status.idle": "2023-08-18T07:07:17.582792Z",
     "shell.execute_reply": "2023-08-18T07:07:17.581735Z"
    },
    "origin_pos": 37,
    "tab": [
     "pytorch"
    ]
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[0.],\n",
       "        [0.]])"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "net = nn.Sequential(MyLinear(64, 8), MyLinear(8, 1))\n",
    "net(torch.rand(2, 64))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  },
  "required_libs": []
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
